import Cesium from '../Ces/Cesium';
import EarthPin from './EarthPin';
import Tooltip from './Tooltip';

class EarthPinCollection {
  _preUpdateRemoveListener
  _objects = new Cesium.AssociativeArray()
  _uniqueToolTip: EarthPin
  constructor(WE) {
    const that = this;
    this._preUpdateRemoveListener = WE.viewer.scene.preUpdate.addEventListener(
      () => {
        that.update(WE.viewer)
      },
    )
  }

  getToolTip(options: any = {}) {
    if (!Cesium.defined(this._uniqueToolTip)) {
      this._uniqueToolTip = new EarthPin({
        id: 'EarthPinCollection.Tooltip',
        graphy: new Tooltip({
          align: options.align || 'right'
        }),
        content: '',
      })
      this._uniqueToolTip.visible = false
    }

    return this._uniqueToolTip;
  }

  getOrCreateToolTip(id, options) {
    let toolTip = this.getById(id)

    if (!toolTip) {
      toolTip = this.add(new EarthPin({
        id,
        graphy: new Tooltip(options),
        content: '',
      }))
    }

    return toolTip;
  }

  add(pin) {
    if (!Cesium.defined(pin)) {
      throw new Cesium.DeveloperError('entity is required.')
    }

    if (!(pin instanceof EarthPin)) {
      pin = new EarthPin(pin)
    }

    const id = pin.id;
    const pins = this._objects;

    if (pins.contains(id)) {
      throw new Cesium.RuntimeError(
        'An pin with id ' + id + ' already exists in this collection.',
      )
    }

    pin.pinCollection = this;
    pins.set(id, pin)

    return pin;
  }

  getById(id) {
    if (!Cesium.defined(id)) {
      throw new Cesium.DeveloperError('id is required.')
    }

    return this._objects.get(id)
  }

  getOrCreate(id) {
    if (!Cesium.defined(id)) {
      throw new Cesium.DeveloperError('id is required.')
    }

    let pin = this._objects.get(id)

    if (!Cesium.defined(pin)) {
      pin = new EarthPin({ id })
      this.add(pin)
    }

    return pin;
  }

  remove(pin) {
    if (!Cesium.defined(pin)) {
      return false;
    }

    if (typeof pin === 'string') {
      return this.removeById(pin)
    }

    if (!Cesium.defined(pin.id)) {
      return false;
    }

    if (!this._objects.remove(pin.id)) {
      return false;
    }

    pin.destroy()

    return true;
  }

  removeById(id) {
    if (!Cesium.defined(id)) {
      return false;
    }

    const pin = this.getById(id)

    if (!Cesium.defined(pin)) {
      return false;
    }

    if (!this._objects.remove(id)) {
      return false;
    }

    pin.destroy()

    return true;
  }

  removeAll() {
    this._objects.values.forEach(pin => {
      pin.destroy()
    })

    this._objects.removeAll()
  }

  update(viewer) {
    this._objects.values.forEach(pin => {
      pin.update(viewer)
    })

    if (this._uniqueToolTip) {
      this._uniqueToolTip.update(viewer)
    }
  }

  destroy() {
    this._preUpdateRemoveListener()
    this.removeAll()
    return Cesium.destroyObject(this)
  }

  isDestroyed() {
    return false
  }
}

export default EarthPinCollection;
